﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Xml;
using Assist;
using Autodesk.Revit.DB;
using Autodesk.Revit.DB.Electrical;
using YArchitech.LIB;
using YArchitech.MEP.Electric.Common;
using YArchitech.Revit;

namespace HYRElectric.PowerSystem
{
	internal class PanelMaterialStatistic
	{
		public PanelMaterialStatistic()
		{
			this.xmlHelper = new YArchitech.MEP.Electric.Common.XmlHelper();
			string xmlPath = Path.Combine(Product.DataLocation, "ElectricalData", "ElectricSystemLoop.xml");
			this.xmlHelper.LoadXml(xmlPath, "Categories");
		}

		public List<MaterialInfo> GetMaterialInfo(Document doc, List<ElementId> lstEquipId)
		{
			if (this.xmlHelper == null)
			{
				return null;
			}
			List<MaterialInfo> list = new List<MaterialInfo>();
			this.xmlHelper.SelectNode("Categories");
			foreach (XmlElement xmlElement in this.xmlHelper.GetElements())
			{
				string attribute = xmlElement.GetAttribute("BuiltInCategory");
				string attribute2 = xmlElement.GetAttribute("Unit");
				List<MaterialInfo> list2 = new List<MaterialInfo>();
				string paramName = string.Empty;
				string value = string.Empty;
				foreach (ElementId elementId in lstEquipId)
				{
					string text = string.Empty;
					string text2 = string.Empty;
					Element element = doc.GetElement(elementId);
					MaterialInfo materialInfo = null;
					bool isWire = false;
                    if (element.Category.Id.IntegerValue.ToString() == attribute && attribute == BuiltInCategory.OST_Wire.ToString())
					{
						isWire = true;
						Wire wire = element as Wire;
						text = wire.Name;
						XmlElement xmlElement2 = xmlElement.SelectSingleNode("FamilyName") as XmlElement;
						XmlNodeList xmlNodeList = xmlElement.SelectNodes("Parameter");
						string str = string.Empty;
						string str2 = string.Empty;
						int i = 0;
						while (i < xmlNodeList.Count)
						{
							xmlElement2 = (xmlNodeList[i] as XmlElement);
							paramName = xmlElement2.GetAttribute("Name");
							value = xmlElement2.GetAttribute("BuiltInParameter");
							if (string.IsNullOrEmpty(value))
							{
								try
								{
									text2 += element.GetParameter(paramName).AsValueString();
									goto IL_1C2;
								}
								catch
								{
									text2 = (text2 ?? "");
									goto IL_1C2;
								}
								goto IL_193;
							}
							goto IL_193;
							IL_1C2:
							str = xmlElement2.GetAttribute("Prefix");
							str2 = xmlElement2.GetAttribute("Suffix");
							text2 = str + text2;
							text2 += str2;
							i++;
							continue;
							IL_193:
							BuiltInParameter parameterId = (BuiltInParameter)Enum.Parse(typeof(BuiltInParameter), value);
							text2 += element.GetParameter(parameterId).AsValueString();
							goto IL_1C2;
						}
						double linearEquipmentlenth = this.GetLinearEquipmentlenth(wire);
						materialInfo = new MaterialInfo(text, text2, linearEquipmentlenth, attribute2);
					}
					else if (element.Category.Id.IntegerValue.ToString() == attribute)
					{
						isWire = false;
						XmlElement xmlElement3 = xmlElement.SelectSingleNode("FamilyName") as XmlElement;
						paramName = xmlElement3.GetAttribute("Name");
						value = xmlElement3.GetAttribute("BuiltInParameter");
						if (string.IsNullOrEmpty(value))
						{
							try
							{
								text += element.GetParameter(paramName).AsString();
								goto IL_2DC;
							}
							catch
							{
								text = (text ?? "");
								goto IL_2DC;
							}
							goto IL_2B4;
						}
						goto IL_2B4;
						IL_2DC:
						XmlNodeList xmlNodeList2 = xmlElement.SelectNodes("Parameter");
						string str3 = string.Empty;
						string str4 = string.Empty;
						int j = 0;
						while (j < xmlNodeList2.Count)
						{
							xmlElement3 = (xmlNodeList2[j] as XmlElement);
							paramName = xmlElement3.GetAttribute("Name");
							value = xmlElement3.GetAttribute("BuiltInParameter");
							if (string.IsNullOrEmpty(value))
							{
								try
								{
									text2 += element.GetParameter(paramName).AsValueString();
									goto IL_38C;
								}
								catch
								{
									text2 = (text2 ?? "");
									goto IL_38C;
								}
								goto IL_35D;
							}
							goto IL_35D;
							IL_38C:
							str3 = xmlElement3.GetAttribute("Prefix");
							str4 = xmlElement3.GetAttribute("Suffix");
							text2 = str3 + text2;
							text2 += str4;
							j++;
							continue;
							IL_35D:
							BuiltInParameter builtInParameter = (BuiltInParameter)Enum.Parse(typeof(BuiltInParameter), value);
							text2 += element.get_Parameter(builtInParameter).AsValueString();
							goto IL_38C;
						}
						materialInfo = new MaterialInfo(text, text2, 1, attribute2);
						goto IL_3E0;
						IL_2B4:
						BuiltInParameter builtInParameter2 = (BuiltInParameter)Enum.Parse(typeof(BuiltInParameter), value);
						text = element.get_Parameter(builtInParameter2).AsString();
						goto IL_2DC;
					}
					IL_3E0:
					if (materialInfo != null && !this.IsExistInList(list2, materialInfo, isWire))
					{
						list2.Add(materialInfo);
					}
				}
				list.AddRange(list2);
			}
			this.xmlHelper.GetAttribute("BuiltInCategory");
			return list;
		}

		private bool IsExistInList(List<MaterialInfo> lst, MaterialInfo item, bool isWire)
		{
			for (int i = 0; i < lst.Count; i++)
			{
				MaterialInfo materialInfo = lst[i];
				if (item.strName.CompareTo(materialInfo.strName) == 0 && item.strSpec.CompareTo(materialInfo.strSpec) == 0)
				{
					if (isWire)
					{
						materialInfo.dLength += item.dLength;
					}
					else
					{
						materialInfo.nCount++;
					}
					return true;
				}
			}
			return false;
		}

		private double GetLinearEquipmentlenth(Wire wire)
		{
			ConnectorSet connectors = wire.ConnectorManager.Connectors;
			if (connectors.Size != 2)
			{
				throw new Exception("导线连接数错误！");
			}
			ConnectorSetIterator connectorSetIterator = connectors.ForwardIterator();
			connectorSetIterator.MoveNext();
			Connector connector = connectorSetIterator.Current as Connector;
			connectorSetIterator.MoveNext();
			Connector connector2 = connectorSetIterator.Current as Connector;
			Connector nativeConnector = this.GetNativeConnector(wire.Id, connector);
			Connector nativeConnector2 = this.GetNativeConnector(wire.Id, connector2);
			XYZ xyz = new XYZ(connector.Origin.X, connector.Origin.Y, 0.0);
			XYZ xyz2 = new XYZ(connector2.Origin.X, connector2.Origin.Y, 0.0);
			double num = xyz.DistanceTo(xyz2);
			double num2 = 0.0;
			if (this.WireRealElevation(wire, ref num2))
			{
				if (nativeConnector != null)
				{
					num += Math.Abs(nativeConnector.Origin.Z - num2);
				}
				if (nativeConnector2 != null)
				{
					num += Math.Abs(nativeConnector2.Origin.Z - num2);
				}
			}
			num = AssistFunc.feetToMM(num) / 1000.0;
			return Math.Round(num, 2);
		}

		private bool WireRealElevation(Wire wire, ref double wireElevation)
		{
			Parameter parameter = wire.GetParameter("相对标高");
			if (parameter != null && parameter.HasValue)
			{
				string text = parameter.AsDouble().ToString("f0");
				if (text.CompareTo("") != 0)
				{
					try
					{
						wireElevation = AssistFunc.mmToFeet(Convert.ToDouble(text) * 1000.0);
						return true;
					}
					catch (Exception)
					{
						return false;
					}
					return false;
				}
			}
			return false;
		}

		private Connector GetNativeConnector(ElementId ownerId, Connector connector)
		{
			ConnectorSetIterator connectorSetIterator = connector.AllRefs.ForwardIterator();
			while (connectorSetIterator.MoveNext())
			{
				object obj = connectorSetIterator.Current;
				Connector connector2 = obj as Connector;
				if (connector2.Owner.Id.IntegerValue != ownerId.IntegerValue)
				{
					return connector2;
				}
			}
			return null;
		}

		private YArchitech.MEP.Electric.Common.XmlHelper xmlHelper;

		private const string root = "Categories";

		private const string category = "Category";

		private const string familyName = "FamilyName";

		private const string parameter = "Parameter";

		private const string name = "Name";

		private const string builtInCategory = "BuiltInCategory";

		private const string unit = "Unit";

		private const string builtInParam = "BuiltInParameter";

		private const string suffix = "Suffix";

		private const string prefix = "Prefix";
	}
}
